/*
 * Copyright 2013-2019 Xia Jun(3979434@qq.com).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 ***************************************************************************************
 *                                                                                     *
 *                        Website : http://www.farsunset.com                           *
 *                                                                                     *
 ***************************************************************************************
 */
package com.workcell.workdata.im.mvc.controller.message;

import com.workcell.workdata.im.annotation.ClientOrigin;
import com.workcell.workdata.im.annotation.CreateAction;
import com.workcell.workdata.im.annotation.UID;
import com.workcell.workdata.im.annotation.UpdateAction;
import com.workcell.workdata.im.component.cim.pusher.MessagePusherProxy;
import com.workcell.workdata.im.constant.MessageAction;
import com.workcell.workdata.im.entity.EventMessage;
import com.workcell.workdata.im.entity.Message;
import com.workcell.workdata.im.model.app.Origin;
import com.workcell.workdata.im.model.request.BatchReadRequest;
import com.workcell.workdata.im.model.request.GroupMessageRequest;
import com.workcell.workdata.im.model.request.MessageForwardRequest;
import com.workcell.workdata.im.model.request.MessageRequest;
import com.workcell.workdata.im.model.response.ResponseEntity;
import com.workcell.workdata.im.service.MessageIndexService;
import com.workcell.workdata.im.service.MessageService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;

@RestController
@RequestMapping("/message")
@Api(produces = "application/json", tags = "消息相关接口" )
@Validated
public class MessageController {

	@Resource
	private MessagePusherProxy messagePusherProxy;

	@Resource
	private MessageService messageService;

	@Resource
	private MessageIndexService messageIndexService;

	@ApiOperation(httpMethod = "POST", value = "发送单人消息")
	@ApiResponses(value = {
			@ApiResponse(responseCode = "200" ,description = "OK"),
			@ApiResponse(responseCode = "403" ,description = "不是好友"),
			@ApiResponse(responseCode = "423" ,description = "被拉黑")})
	@PostMapping(value = "")
	@Validated(CreateAction.class)
	public ResponseEntity<?> send(@ApiIgnore @UID Long uid , @ApiIgnore @ClientOrigin Origin origin , @Valid @RequestBody MessageRequest request) {

		Message message = request.ofMessage();

		message.setSender(uid);

		return messagePusherProxy.push(message,origin);
	}

	@ApiOperation(httpMethod = "POST", value = "发送群聊消息")
	@ApiResponses(value = {
			@ApiResponse(responseCode = "200" ,description = "OK"),
			@ApiResponse(responseCode = "423" ,description = "被禁止发言")})
	@PostMapping(value = "/group")
	@Validated(CreateAction.class)
	public ResponseEntity<?> sendGroup(@ApiIgnore @UID Long uid , @ApiIgnore @ClientOrigin Origin origin , @Valid @RequestBody GroupMessageRequest request) {

		Message message = request.ofMessage();
		message.setSender(uid);

		return messagePusherProxy.push(message,origin);
	}

	@ApiOperation(httpMethod = "POST", value = "阅读消息")
	@ApiImplicitParam(name = "id", value = "消息ID", paramType = "path",  dataTypeClass = Long.class,example = "0")
	@PostMapping(value = "/read/{id}")
	public ResponseEntity<Void> read(@PathVariable Long id) {
		messageService.read(id);
		return ResponseEntity.ok();
	}

	@ApiOperation(httpMethod = "POST", value = "阅读消息并通知对方")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "id", value = "消息ID", paramType = "path",  dataTypeClass = Long.class,example = "0"),
			@ApiImplicitParam(name = "receiver", value = "用户ID", paramType = "path",  dataTypeClass = Long.class,example = "0")
	})
	@PostMapping(value = "/read/{id}/{receiver}")
	public ResponseEntity<Void> read(@ApiIgnore @UID Long uid , @ApiIgnore @ClientOrigin Origin origin ,@PathVariable Long id, @PathVariable Long receiver) {

		messageService.read(id);

		Message message = new EventMessage();
		message.setSender(uid);
		message.setContent(String.valueOf(id));
		message.setReceiver(receiver);
		message.setAction(MessageAction.ACTION_100);

		messagePusherProxy.push(message,origin);
		
		return ResponseEntity.ok();
	}

	@ApiOperation(httpMethod = "POST", value = "批量阅读消息并通知对方")
	@PostMapping(value = "/read/batch")
	@Validated(UpdateAction.class)
	public ResponseEntity<Void> batchRead(@ApiIgnore @UID Long uid ,@ApiIgnore @ClientOrigin Origin origin , @Valid @RequestBody BatchReadRequest request) {

		messageService.read(request.getIdList());

		for (Long id : request.getIdList()){
			Message message = new EventMessage();
			message.setSender(uid);
			message.setContent(String.valueOf(id));
			message.setReceiver(request.getUid());
			message.setAction(MessageAction.ACTION_100);
			messagePusherProxy.push(message,origin);
		}

		return ResponseEntity.ok();
	}

	@ApiOperation(httpMethod = "POST", value = "设置已接收状态")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "id", value = "消息ID", paramType = "path",  dataTypeClass = Long.class,example = "0"),
			@ApiImplicitParam(name = "action", value = "消息类型", paramType = "query",  dataTypeClass = String.class,example = "0")
	})
	@PostMapping(value = "/receive/{id}")
	public ResponseEntity<Void> receive(@ApiIgnore @UID Long uid ,@PathVariable Long id ,@RequestParam String action) {
		messageIndexService.receive(uid,id,action);
		return ResponseEntity.ok();
	}


	@ApiOperation(httpMethod = "POST", value = "设置所有消息已接收状态")
	@PostMapping(value = "/receive/all")
	public ResponseEntity<Void> receiveAll(@ApiIgnore @UID Long uid) {
		messageIndexService.delete(uid);
		return ResponseEntity.ok();
	}

	@ApiOperation(httpMethod = "POST", value = "转发消息")
	@PostMapping(value = "/forward")
	@Validated(CreateAction.class)
	public ResponseEntity<List<MessageForwardRequest.MessageReceiver>> forward(@ApiIgnore @UID Long uid, @ApiIgnore @ClientOrigin Origin origin , @Valid @RequestBody MessageForwardRequest request) {

		List<MessageForwardRequest.MessageReceiver> receivers = request.getReceiver();

		for (MessageForwardRequest.MessageReceiver receiver : receivers){

			Message message = request.ofMessage(receiver.getAction());

			message.setSender(uid);

			message.setReceiver(receiver.getId());

			messagePusherProxy.push(message,origin);

			receiver.setMid(message.getId());
			receiver.setTimestamp(System.currentTimeMillis());
		}

		return ResponseEntity.ok(receivers);
	}

	@ApiOperation(httpMethod = "DELETE", value = "撤回消息")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "id", value = "消息ID", paramType = "path",  dataTypeClass = Long.class,example = "0"),
			@ApiImplicitParam(name = "action", value = "消息类型", paramType = "query",  dataTypeClass = String.class,example = "0")
	})
	@DeleteMapping(value = "/revoke/{id}")
	public ResponseEntity<Void> revoke(@ApiIgnore @UID Long uid,@PathVariable Long id ,@RequestParam String action) {

		messageIndexService.revoke(uid,id,action);

		return ResponseEntity.ok();
	}

	@ApiOperation(httpMethod = "POST", value = "发送正在输入事件",notes = "对方聊天窗口显示正在输入中....")
	@ApiImplicitParam(name = "uid", value = "好友UID", paramType = "query",  dataTypeClass = Long.class,example = "0")
	@PostMapping(value = "/typing")
	public ResponseEntity<Void> typing(@ApiIgnore @UID Long selfId ,@ApiIgnore @ClientOrigin Origin origin ,@RequestParam Long uid) {

		Message message = new EventMessage();
		message.setSender(selfId);
		message.setReceiver(uid);
		message.setAction(MessageAction.ACTION_108);

		messagePusherProxy.push(message,origin);

		return ResponseEntity.ok();
	}
}
